package com.whfc.mach.service.impl;

import com.whfc.common.enums.NetState;
import com.whfc.common.exception.BizException;
import com.whfc.common.util.MathUtil;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.mach.dao.AppMachDataMapper;
import com.whfc.mach.dao.AppMachDayMapper;
import com.whfc.mach.dao.AppMachMapper;
import com.whfc.mach.dao.AppMachOperEmpMapper;
import com.whfc.mach.dto.*;
import com.whfc.mach.dto.warn.AppMachWarnCountDTO;
import com.whfc.mach.manager.MachMgr;
import com.whfc.mach.manager.MachWarnManager;
import com.whfc.mach.manager.util.MachUtil;
import com.whfc.mach.service.AppMachBoardService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @author qzexing
 * @version 1.0
 * @date 2020-11-12 19:47
 */
@DubboService(interfaceClass = AppMachBoardService.class, version = "1.0.0", timeout = 10000)
public class AppMachBoardServiceImpl implements AppMachBoardService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AppMachMapper appMachMapper;

    @Autowired
    private AppMachDataMapper appMachDataMapper;

    @Autowired
    private AppMachDayMapper appMachDayMapper;

    @Autowired
    private AppMachOperEmpMapper appMachOperEmpMapper;

    @Autowired
    private MachWarnManager machWarnManager;

    @Autowired
    private MachMgr machMgr;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;


    @Override
    public AppBoardMachOverviewDTO machRunData(Integer deptId, Date startDate, Date endDate) {
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        AppBoardMachOverviewDTO data = new AppBoardMachOverviewDTO();

        //雷达图数据
        MachRadarMapDTO radarMapDTO = appMachDayMapper.selectMultiMachRadarMap(deptIds, startDate, endDate);
        AppBoardMachRadarMapDTO machRadarMap = new AppBoardMachRadarMapDTO();
        machRadarMap.setEfficExp(radarMapDTO.getEfficExp());
        machRadarMap.setOilExp(radarMapDTO.getOilExp());
        machRadarMap.setSafeExp(radarMapDTO.getSafeExp());
        machRadarMap.setStableExp(radarMapDTO.getStabExp());
        machRadarMap.setStrengthExp(radarMapDTO.getStrengthExp());
        data.setMachRadarMap(machRadarMap);

        // 每日数据统计
        List<MachCurveMapDayDTO> list = appMachDayMapper.selectMultiMachCurveMapDayList(deptIds, startDate, endDate);
        List<AppBoardWeekDataDTO> weekDataList = dailyDataHandler(list);
        data.setWeekDataList(weekDataList);
        return data;
    }


    @Override
    public AppBoardMachOverviewDTO machList(Integer deptId) {
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        // 查询设备列表
        List<AppMachDTO> appMachList = appMachMapper.selectBoardMachDTOList(deptIds);
        AppBoardMachOverviewDTO data = machDeviceStatistics(appMachList);
        // 报警次数统计
        AppMachWarnCountDTO warnCountDTO = machWarnManager.machWarnStatistics(deptId, null);
        data.setMachWarnCountDTO(warnCountDTO);
        return data;
    }

    @Override
    public List<GisMachDTO> getGisMachData(Integer deptId) {
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<GisMachDTO> list = appMachMapper.selectGisMachData(deptIds);
        for (GisMachDTO gisMachDTO : list) {
            Integer machId = gisMachDTO.getId();
            List<MachOperEmpDTO> appMachOperEmpList = appMachOperEmpMapper.selectByMachId(machId);
            gisMachDTO.setMachOperEmpList(appMachOperEmpList);
        }
        return list;
    }

    @Override
    public BoardMachNumDTO statMachNum(Integer deptId) throws BizException {
        logger.info("大屏统计设备数服务,deptId:{}", deptId);
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<AppMachDTO> list = appMachDataMapper.selectMachData(deptIds, null, null, null);
        BoardMachNumDTO data = new BoardMachNumDTO();
        data.setNum(list.size());
        data.setOnlineNum((int) list.stream().filter(a -> NetState.ONLINE.getValue().equals(a.getNetState())).count());
        return data;
    }


    /***********************************  private ***********************************/


    /**
     * 设备状态统计
     *
     * @param appMachList 设备列表
     * @return 设备状态统计
     */
    private AppBoardMachOverviewDTO machDeviceStatistics(List<AppMachDTO> appMachList) {
        AppBoardMachOverviewDTO data = new AppBoardMachOverviewDTO();
        List<AppBoardMachDTO> machList = new ArrayList<>();
        Set<String> machTypeNameSet = new HashSet<>();
        for (AppMachDTO appMachDTO : appMachList) {
            machTypeNameSet.add(appMachDTO.getMachTypeName());
            Integer workState = appMachDTO.getWorkState();

            AppBoardMachDTO appBoardMachDTO = new AppBoardMachDTO();
            appBoardMachDTO.setMachCode(appMachDTO.getMachCode());
            appBoardMachDTO.setNetState(appMachDTO.getNetState());
            appBoardMachDTO.setWorkState(workState);
            appBoardMachDTO.setMachTypeName(appMachDTO.getMachTypeName());
            appBoardMachDTO.setWorkTimes(appMachDTO.getWorkTimes());
            appBoardMachDTO.setIdleTimes(appMachDTO.getIdleTimes());
            appBoardMachDTO.setTotalTimes(MathUtil.round(appMachDTO.getWorkTimes() + appMachDTO.getIdleTimes(), 2));

            //状态持续时长
            if (appMachDTO.getWorkStateStartTime() != null) {
                appBoardMachDTO.setTime(appMachDTO.getWorkStateStartTime());
                appBoardMachDTO.setDuration((System.currentTimeMillis() - appMachDTO.getWorkStateStartTime().getTime()) / 1000);
            }

            //操作手
            List<MachOperEmpDTO> machOperatorList = appMachOperEmpMapper.selectByMachId(appMachDTO.getId());
            appBoardMachDTO.setOperEmpList(machOperatorList);

            //油位
            Integer oilPos1 = appMachDTO.getOilPos();
            Double oilTankHeight = appMachDTO.getOilTankHeight();
            Double oilTankVolume = appMachDTO.getOilTankVolume();
            if (ObjectUtils.allNotNull(oilPos1, oilTankHeight, oilTankVolume) && oilTankHeight > 0 && oilTankVolume > 0) {
                double oilPos = 0.1 * oilPos1;
                if (oilPos < 0) {
                    oilPos = 0D;
                }
                if (oilPos > oilTankHeight) {
                    oilPos = oilTankHeight;
                }

                appBoardMachDTO.setRemainOilPercent(MathUtil.round(100 * oilPos / oilTankHeight, 1));
                appBoardMachDTO.setRemainOil(MathUtil.round(oilTankVolume * oilPos / oilTankHeight, 2));
            }
            machList.add(appBoardMachDTO);
        }

        // 设备数量统计
        data.setBoardMachNumDTO(machMgr.getBoardMachNumDTO(machList, machTypeNameSet));

        data.setMachList(machList);
        return data;
    }

    /**
     * 日均数据处理
     *
     * @param list
     * @return
     */
    private List<AppBoardWeekDataDTO> dailyDataHandler(List<MachCurveMapDayDTO> list) {
        List<AppBoardWeekDataDTO> weekDataList = new ArrayList<>();
        for (MachCurveMapDayDTO dayDTO : list) {
            Double operatingRate = MachUtil.computeOperatingRate(dayDTO.getWorkMachNum(), dayDTO.getTotalMachNum());
            AppBoardWeekDataDTO appBoardWeekDataDTO = new AppBoardWeekDataDTO();
            appBoardWeekDataDTO.setDate(dayDTO.getDate());
            appBoardWeekDataDTO.setWorkTimes(dayDTO.getWorkTimes());
            appBoardWeekDataDTO.setEfficExp(dayDTO.getEfficExp());
            appBoardWeekDataDTO.setOperatingRate(operatingRate);
            appBoardWeekDataDTO.setOilWear(dayDTO.getOilWear());
            weekDataList.add(appBoardWeekDataDTO);
        }
        return weekDataList;
    }
}
